#include <iostream>
#include <cstring>
#include <cerrno>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

int main(int argc, char* args[])
{
    if(argc != 3)
    {
        std::cout << "Usage: \n";
        std::cout << args[0] << " IP port\n";
        return 0;
    }
    uint16_t port = std::stoi(args[2]);
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0)
    {
        std::cout << "socket failed, errno : " << strerror(errno) << std::endl;
        return 0;
    }
    std::cout << "socket success, sockfd : " << sockfd << std::endl;

    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(args[1]);
    // int n = bind(sockfd, (struct sockaddr*)&server, sizeof(server)); // 不需要手动绑定，OS会帮我们做
    int n = connect(sockfd, (struct sockaddr*)&server, sizeof(server));
    if(n < 0)
    {
        std::cout << "connect failed, errno : " << strerror(errno) << std::endl;
        return 0;
    }
    
    std::string message;
    char buffer[1024];
    while(1)
    {
        std::cout << "enter # ";
        std::getline(std::cin, message);
        int n = send(sockfd, message.c_str(), message.size(), 0);
        if(n < 0)
        {
            std::cout << "send failed, error: " << strerror(errno) << std::endl;
            break;
        }
        
        struct sockaddr_in tmp;
        socklen_t sz = sizeof(tmp);
        n = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
        if(n > 0)
        {
            buffer[n] = 0;
            std::cout << "server # " << buffer << std::endl;
        }
        else if(n == 0)
        {
            std::cout << "退出" << std::endl;
            break;
        }
        else
        {
            std::cout << "recv failed, error: " << strerror(errno) << std::endl;
            break;
        }
    }
    close(sockfd);
    return 0;
}
